package net.peelmeagrape.hibernate;

import net.peelmeagrape.hibernate.xmlgen.*;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
 * For a table with a composite key, you may map multiple properties of the class as identifier properties.
 * e.g.:
 * <pre>        &#64;{@link CompositeId} CustomId id;
</pre>
 * and:
 * <pre>
    class CustomId {
        &#64;{@link net.peelmeagrape.hibernate.collections.KeyProperty} String field1;
        &#64;{@link net.peelmeagrape.hibernate.collections.KeyProperty} String field2;
        &#64;{@link net.peelmeagrape.hibernate.collections.KeyManyToOne} SomeEntity entity;
    }
 </pre>
 * Annotations from the composite id class will be processed. Fields in the composite id should be annotated
 * using {@link net.peelmeagrape.hibernate.collections.KeyProperty} and {@link net.peelmeagrape.hibernate.collections.KeyManyToOne}.
 * Your id class must override {@link Object#equals(Object)} and
 * {@link Object#hashCode()} to implement composite identifier equality.
 * It must also implement {@link java.io.Serializable}.
 * <br/>
 * <b>todo:</b> H8A8 does not support composite id without using <a href="">Components as Composite Identifiers</a>.
 */
@Target({METHOD,FIELD}) @Retention(RUNTIME)
@XmlElement(name="composite-id")
@AddPropertyNameAsAttribute(name="name")
public @interface CompositeId
{
    @XmlAttribute("class")
            @DefaultFromPropertyType
            @ProcessTargetClass()
            Class[] targetClass() default {};

    /**
     * The strategy Hibernate should use for accessing the property value. This may be one of
     * 'property', 'field', 'embedded', or the name of a subclass of {@link org.hibernate.property.PropertyAccessor}.
     */
    @XmlAttribute String access() default "property";

    /**
     * Mapping to xml.
     */
    @XmlAttribute String node() default "";

    /**
     * (optional - defaults to undefined): Indicates that transient instances should be considered newly
     * instantiated, if set to any, or detached, if set to none. It is best to leave the default value in all cases.
     */
    @XmlAttribute("unsaved-value") String unsavedValue() default "none";

    @ChildElement(0) Meta[] meta() default {};
}
